aboutsummaryrefslogtreecommitdiff
path: root/src/app/(main)/websites/[websiteId]/realtime/RealtimePage.tsx
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-01-24 13:09:50 +0000
committerFuwn <[email protected]>2026-01-24 13:09:50 +0000
commit396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b (patch)
treeb9df4ca6a70db45cfffbae6fdd7252e20fb8e93c /src/app/(main)/websites/[websiteId]/realtime/RealtimePage.tsx
downloadumami-main.tar.xz
umami-main.zip
Initial commitHEADmain
Created from https://vercel.com/new
Diffstat (limited to 'src/app/(main)/websites/[websiteId]/realtime/RealtimePage.tsx')
-rw-r--r--src/app/(main)/websites/[websiteId]/realtime/RealtimePage.tsx58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/app/(main)/websites/[websiteId]/realtime/RealtimePage.tsx b/src/app/(main)/websites/[websiteId]/realtime/RealtimePage.tsx
new file mode 100644
index 0000000..6220c69
--- /dev/null
+++ b/src/app/(main)/websites/[websiteId]/realtime/RealtimePage.tsx
@@ -0,0 +1,58 @@
+'use client';
+import { Grid } from '@umami/react-zen';
+import { firstBy } from 'thenby';
+import { GridRow } from '@/components/common/GridRow';
+import { PageBody } from '@/components/common/PageBody';
+import { Panel } from '@/components/common/Panel';
+import { useMobile, useRealtimeQuery } from '@/components/hooks';
+import { RealtimeChart } from '@/components/metrics/RealtimeChart';
+import { WorldMap } from '@/components/metrics/WorldMap';
+import { percentFilter } from '@/lib/filters';
+import { RealtimeCountries } from './RealtimeCountries';
+import { RealtimeHeader } from './RealtimeHeader';
+import { RealtimeLog } from './RealtimeLog';
+import { RealtimePaths } from './RealtimePaths';
+import { RealtimeReferrers } from './RealtimeReferrers';
+
+export function RealtimePage({ websiteId }: { websiteId: string }) {
+ const { data, isLoading, error } = useRealtimeQuery(websiteId);
+ const { isMobile } = useMobile();
+
+ if (isLoading || error) {
+ return <PageBody isLoading={isLoading} error={error} />;
+ }
+
+ const countries = percentFilter(
+ Object.keys(data.countries)
+ .map(key => ({ x: key, y: data.countries[key] }))
+ .sort(firstBy('y', -1)),
+ );
+
+ return (
+ <Grid gap="3">
+ <RealtimeHeader data={data} />
+ <Panel>
+ <RealtimeChart data={data} unit="minute" />
+ </Panel>
+ <Panel>
+ <RealtimeLog data={data} />
+ </Panel>
+ <GridRow layout="two">
+ <Panel>
+ <RealtimePaths data={data} />
+ </Panel>
+ <Panel>
+ <RealtimeReferrers data={data} />
+ </Panel>
+ </GridRow>
+ <GridRow layout="one-two">
+ <Panel>
+ <RealtimeCountries data={countries} />
+ </Panel>
+ <Panel gridColumn={isMobile ? null : 'span 2'} padding="0">
+ <WorldMap data={countries} />
+ </Panel>
+ </GridRow>
+ </Grid>
+ );
+}